﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Company.Project.Application.Service.CacheService;
using Company.Project.Application.Service.Interface;
using Company.Project.Domain.Model.DTO.Manager;
using Company.Utility;
using Company.Utility.CustomerAttribute;
using Company.Utility.Encrypt;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Routing;
using Newtonsoft.Json;
using HttpContext = Company.Utility.HttpContext;
using Company.Utility.Extensions;
namespace Company.Project.Web.Admin.Areas.Admin.Lib
{
    public interface ILocalCommon
    {
        LoginUserDTO CurrentFullUser();
        Task<LoginUserDTO> CurrentFullUserAsync();
        string GetColumsName<T>(params JqGridOpt[] opt);
        Dictionary<string, string> GetExportColumsName<T>();
    }
    public class LocalCommon: ILocalCommon
    {
        private readonly IProject_SYS_BaseCacheService _cacheService;
        private readonly IProject_Manager_BaseInfoServices _baseInfoServices;
        public static List<Tuple<string, string>> cacheColumsName;
        public LocalCommon(IProject_SYS_BaseCacheService cacheService, IProject_Manager_BaseInfoServices baseInfoServices)
        {
            _cacheService = cacheService;
            _baseInfoServices = baseInfoServices;
        }

        private LoginUserDTO CookieUser()
        {
            var result =HttpContext.Current.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme).Result;
            if (result.Succeeded)
            {
                var user = HttpContext.Current.User.FindFirst(ClaimTypes.UserData).Value;
                return JsonConvert.DeserializeObject<LoginUserDTO>(user);
            }
            else
            {
                LoggerHelper.Log("授权异常(InitSession):");
            }
            return new LoginUserDTO();
        }
        public LoginUserDTO CurrentFullUser()
        {
            var user = CookieUser();
            if (user.ID != Guid.Empty)
            {
                try
                {
                    var cache = _cacheService.GetAllLogin().FirstOrDefault(x => x.ID == user.ID);
                    if (cache != null)
                    {
                        user = cache;
                    }
                    else
                    {
                        user.DefActionList = new List<RoleAction_ModuleDTO>();
                        user.UserActionList = new List<RoleActionDTO>();
                    }
                }
                catch (Exception e)
                {
                    LoggerHelper.Log("授权异常(InitSession):" + e.Message + ",基础异常:" + e.GetBaseException()?.Message);
                    user.DefActionList = new List<RoleAction_ModuleDTO>();
                    user.UserActionList = new List<RoleActionDTO>();
                }
            }
            return user;
        }
        public async Task<LoginUserDTO> CurrentFullUserAsync()
        {
            var user = CookieUser();
            if (user.ID != Guid.Empty)
            {
                try
                {
                    var cache = _cacheService.GetAllLogin().FirstOrDefault(x => x.ID == user.ID);
                    if (cache == null)
                    {
                        await _baseInfoServices.CheckLogin(user.LoginName, user.PassWord, false, true);
                        cache = _cacheService.GetAllLogin().FirstOrDefault(x => x.ID == user.ID);
                    }
                    user = cache;
                }
                catch (Exception e)
                {
                    LoggerHelper.Log("授权异常(InitSession):" + e.Message + ",基础异常:" + e.GetBaseException()?.Message);
                    user.DefActionList = new List<RoleAction_ModuleDTO>();
                    user.UserActionList = new List<RoleActionDTO>();
                }
            }
            return user;
        }
        public Dictionary<string, string> GetExportColumsName<T>()
        {
            var def = new Dictionary<string, string>();
            typeof(T).GetProperties()
                .Where(
                    x =>
                        !x.GetMethod.IsVirtual).ToList()
                .ForEach(x => { def.Add("_" + x.Name, x.GetCustomAttribute<DisplayNameAttribute>().DisplayName); });
            return def;
        }
        public string GetColumsName<T>(params JqGridOpt[] opt)
        {
            if (cacheColumsName != null)
            {
                if (cacheColumsName.Exists(x => x.Item1 == typeof(T).Name))
                {
                    return cacheColumsName.FirstOrDefault(x => x.Item1 == typeof(T).Name)?.Item2;
                }
            }
            else
            {
                //create
                cacheColumsName = new List<Tuple<string, string>>();
            }
          
            var title = new List<string>();
            title.Add("{ name: 'id', index: 'id',hidden :true }");
            title.Add("{ id: 'EditOpt',name:'', index: 'id',width:35, align: 'center',fixed: true, sortable: false, resize: false, formatter:editIcon }");
            typeof(T).GetProperties()
                .Where(
                    x =>
                        !x.GetMethod.IsVirtual)
                .Select(x => new
                {
                    x.Name,
                    x.GetCustomAttribute<DisplayNameAttribute>().DisplayName,
                    x.GetCustomAttribute<JqGridColumnOpt>()?.Width,
                    x.GetCustomAttribute<JqGridColumnOpt>()?.Align,
                    x.GetCustomAttribute<JqGridColumnOpt>()?.IsSort,
                    x.GetCustomAttribute<JqGridColumnOpt>()?.SortName,
                    x.GetCustomAttribute<JqGridColumnOpt>()?.RenderFun,
                    x.GetCustomAttribute<JqGridColumnOpt>()?.IsHidden,
                }).ToList().ForEach(x =>
                {
                    title.Add("{ label:'" + x.DisplayName + "', name: '" + x.Name.ReplaceCamelString() + "', index: '" +
                              (string.IsNullOrEmpty(x.SortName) ? x.Name.ReplaceCamelString() : x.SortName.ReplaceCamelString()) + "'" +
                              (x.Width != null && x.Width != 0 ? ",fixed: true,width: " + x.Width : "") +
                              (x.Align != null ? ",align:'" + x.Align + "'" : "") +
                              (x.IsSort != null ? x.IsSort.Value ? ",sortable:true" : ",sortable:false" : "") +
                              (string.IsNullOrEmpty(x.RenderFun) ? "" : ",formatter: " + x.RenderFun) +
                              (x.IsHidden != null ? x.IsHidden.Value ? ",hidden:true" : ",hidden:false" : "") +
                              " }");
                });
            if (opt.Any())
            {
                opt.ToList().ForEach(x =>
                {
                    title.Add("{ label:'" + x.Title + "',name: '" + x.Title.ReplaceCamelString() + "', index: 'id',width: " + x.OptWidth + ",align: 'center',fixed: true, sortable: false, resize: false, formatter: " + x.OptMainFun + " }");
                });
            }
            cacheColumsName.Add(new Tuple<string, string>(typeof(T).Name, string.Join(",", title)));
            _cacheService.Add("JqColumsName", cacheColumsName);
            return string.Join(",", title);
        }
    }
}
